/**
 * Copyright (c) 2012-2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */
package com.nokia.example.fuelcalculator.view;

import com.nokia.example.fuelcalculator.Midlet;
import com.nokia.example.fuelcalculator.l10n.L10NIDs;
import com.nokia.example.fuelcalculator.l10n.Localizer;
import com.nokia.example.fuelcalculator.model.FuelConsumptionModel;
import com.nokia.example.fuelcalculator.model.ModelObject;
import com.nokia.example.fuelcalculator.utils.Commands;
import com.nokia.example.fuelcalculator.utils.Consumption;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;

/**
 * This is the view that summaries the entries from the consumption log.
 */
public final class TotalConsumptionView
        implements CommandListener, View {
    
    private static String LOG_LINE_SPACES = "      ";
    private Form form;
    private Localizer localizer;
    private ViewManager viewManager;
    private FuelConsumptionModel model;
    private StringItem firstTimeField;
    private StringItem averageConsumptionField;
    private StringItem consumptionLogField;

    /**
     * Constructor.
     * @param viewManager 
     */
    public TotalConsumptionView(ViewManager viewManager) {    
        this.viewManager = viewManager;
        this.localizer = Localizer.getInstance();
        this.model = Midlet.getInstance().getFuelConsumptionModel();
        
        this.form = new Form(
                localizer.getString(L10NIDs.TOTAL_CONSUMPTION_VIEW_TITLE));
        initializeLabels();
        form.setCommandListener(this);
    }

    /**
     * @see fuelconsumption.view.View#updateUI()
     */
    public void updateUI() {
        boolean firstTime = model.isEmpty();
        
        form.deleteAll();
        clearCommands();
        
        addFields(firstTime);
        addCommands(firstTime);
    }

    /**
     * @see fuelconsumption.view.View#updateUI()
     */
    public Displayable getDisplayable() {
        return form;
    }

    /**
     * @see javax.microedition.lcdui.CommandListener#commandAction(Command, Displayable)
     */
    public void commandAction(Command c, Displayable d) {
        if (c == Commands.DELETE_LATEST_CONSUMPTION_ACTION) {
            model.deleteLatest();
            viewManager.showEnterView();
        } else {
            viewManager.commandAction(c, d);
        }
    }

    private void initializeLabels() {
        // if the model is empty show this
        firstTimeField = new StringItem(
                null,
                localizer.getString(L10NIDs.TOTAL_CONSUMPTION_VIEW_FIRST_TIME_FIELD_TEXT));
        firstTimeField.setLayout(Item.LAYOUT_CENTER | Item.LAYOUT_VCENTER);
        
        // ..otherwise these is to be shown
        averageConsumptionField = new StringItem(
                localizer.getString(L10NIDs.TOTAL_CONSUMPTION_VIEW_AVERAGE_CONSUMPTION_FIELD_TITLE),
                null);
        consumptionLogField = new StringItem(
                localizer.getString(L10NIDs.TOTAL_CONSUMPTION_VIEW_CONSUMPTION_LOG_FIELD_TITLE),
                null);
        consumptionLogField.setFont(Font.getFont(
                Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL));
    }
    
    private String generateAverageConsumptionText() {
        StringBuffer sb = new StringBuffer();
        double averageConsumption = calculateAverageConsumption();
        sb.append(localizer.formatConsumption(averageConsumption));
        sb.append(" ");
        sb.append(localizer.getString(L10NIDs.TOTAL_CONSUMPTION_VIEW_AVG_CONSUMPTION_FOOTER));
        return sb.toString();
    }
    
    private String generateConsumptionLogText() {
        StringBuffer sb = new StringBuffer();
        ModelObject obj;
        double volume;
        int distance;
        double consumption;
        StringBuffer lineBuf;
             
        for (int i = model.getSize()-1; i >=0; i--) {
            obj = model.getObjectAt(i);
            volume = obj.getVolume();
            distance = obj.getDistance();
            consumption = Consumption.calculate(volume, distance);
            
            lineBuf = createConsumptionLogLine(
                localizer.formatDate(obj.getDate()),
                localizer.formatConsumption(consumption));
                
            sb.append(lineBuf);
        }
               
        return sb.toString();
    }
    
    private double calculateAverageConsumption() {
        float volumes = 0.0f;
        int distances = 0;
        ModelObject obj;

        for (int i = 0; i < model.getSize(); i++) {
            obj = model.getObjectAt(i);
            volumes += obj.getVolume();
            distances += obj.getDistance();
        }

        return Consumption.calculate(volumes, distances);
    }
    
    private void addFields(boolean firstTime) {
        if (firstTime) {
            form.append(firstTimeField);
        } else {
            averageConsumptionField.setText(generateAverageConsumptionText());
            consumptionLogField.setText(generateConsumptionLogText());
            form.append(averageConsumptionField);
            form.append(consumptionLogField);
        }
    }

    private void clearCommands() {
        form.removeCommand(Commands.GOTO_ADD_FILLING_VIEW);
        form.removeCommand(Commands.GOTO_ABOUT_VIEW);
        form.removeCommand(Commands.GOTO_HELP_VIEW);
        form.removeCommand(Commands.DELETE_LATEST_CONSUMPTION_ACTION);
        form.removeCommand(Commands.EXIT);
    }
    
    private void addCommands(boolean firstTime) {
        form.addCommand(Commands.GOTO_ADD_FILLING_VIEW);
        form.addCommand(Commands.GOTO_ABOUT_VIEW);
        form.addCommand(Commands.GOTO_HELP_VIEW);
        if (!firstTime) {
            form.addCommand(Commands.DELETE_LATEST_CONSUMPTION_ACTION);
        }
        form.addCommand(Commands.EXIT);
    }
    
    /*
     * Creates a consumption log line that based on the used phone language.
     * LTR and RTL has a different presentation order.
     */
    private StringBuffer createConsumptionLogLine(String date, String consumption) {
        StringBuffer sb = new StringBuffer();
        
        String left;
        String right;
        
        if (localizer.phoneLanguageIsRTL()) {
            left = consumption;
            right = date;
        } else {
            left = date;
            right = consumption;
        }
        
        sb.append(left);
        sb.append(LOG_LINE_SPACES);
        sb.append(right);
        sb.append("\n");
        
        return sb;
    }
}
